//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "ia\fn_stuckUnit.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_unit"];
_unit = _this;
if (IS_ARRAY(_unit)) then {
	DEFAULT_PARAM(_unit,0,objNull);
};
if (AND_ALSO(AND_ALSO(IS_OBJECT(_unit),!isNull _unit),(_unit isKindOf "Man"))) then {
	_unit disableAI "MOVE";
	_unit spawn {
		private ["_unit","_initial_pos","_chance_move","_targets","_nearest_enemy_pos","_nearest_target","_nearest_enemy_dist","_perceived_side","_perceived_pos","_dist","_x","_start_dir","_end_dir"
				,"_rotation","_incr","_i","_last_target","_unit_side","_initial_pos_asl","_nearest_target_obj","_nearest_target_type","_nearest_enemy_cost"];
		_unit = _this;
		_initial_pos = getPos _unit;
		_initial_pos_asl = getPosASL _unit;
		_chance_move = 0;
		_last_target = objNull;
		_unit_side = side _unit;
		DEBUG_1("Starting Watch", ARR_3(_unit, typeof _unit,_unit_side));
		while { alive _unit } do {
			sleep 0.12345;
			_targets = _unit nearTargets 600;
			if (count _targets > 0) then {
				_nearest_enemy_pos = [];
				_dist = 0;
				_cost = 0;
				_nearest_enemy_cost = 0;
				_nearest_target = objNull;
				_nearest_enemy_dist = 1000;
				{
					// [[2555.33,2535.33,1.32708],"SoldierEB",EAST,214222,EAST 1-1-A:1]
					_perceived_side = (_x select 2);
					if ((_unit_side getFriend _perceived_side) < 0.6) then {
						_perceived_pos = (_x select 0);
						_dist = _perceived_pos distance _unit;
						_cost = (_x select 3);
						if (_dist < _nearest_enemy_dist && (_cost / _dist) >= (_nearest_enemy_cost / _nearest_enemy_dist)) then {
							_nearest_enemy_pos = _perceived_pos;
							_nearest_enemy_dist = _dist;
							_nearest_enemy_cost = _cost;
							_nearest_target = _x;
						};
					};
				} foreach _targets;
				if (count _nearest_enemy_pos > 0) then {
					_nearest_target_obj = _nearest_target select 4;
					_nearest_target_type = _nearest_target select 1;
					_nearest_target_side = _nearest_target select 2;
					
					if (_last_target != _nearest_target_obj) then {
						_last_target = _nearest_target_obj;
						DEBUG_1("Aligning Target", ARR_3(_unit, typeof _unit, _nearest_target));
					};
					_start_dir = floor(getDir _unit);
					_end_dir = floor([_unit, _nearest_enemy_pos,_start_dir] call FFUNC(dirTo));
					if (_end_dir < 0) then {_end_dir = 360 + _end_dir; };
					_rotation = floor(_end_dir - _start_dir);
					_incr = 1;
					if (_rotation < 0) then {
						_incr = -1;
					};
					if (_rotation >= 180) then {
						_rotation = 360 - _rotation;
						_incr = -1;
					};
					TRACE_1("Turning",ARR_7(_nearest_enemy_pos, (_nearest_enemy_pos distance _unit), _start_dir, _end_dir, _rotation, (_start_dir + _rotation), _incr));
					for [{_i = _start_dir}, {abs(abs(_end_dir) - abs(floor(getDir _unit))) > 2}, { _i = _i + _incr}] do {
						if (!alive _unit) exitWith{};
						_unit setDir _i;
						sleep 0.003;
					};
				} else {
					_chance_move = _chance_move + 1;
					if (_chance_move > 100) then {
						_chance_move = 0;
						if (random(10) > 7) then {
							_start_dir = floor(getDir _unit);
							_end_dir = floor(_start_dir + random(180));
							for [{_i = _start_dir}, {abs(abs(_i) - abs(_end_dir)) <= 1}, { _i = _i + 1}] do {
								_unit setDir _i;
								sleep 0.01;
							};
						};
					};
				};
			};
		};
	};
} else {
	ERROR("Invalid Unit");
};

TRACE("End");
TMFPROFILERSTOP;